package com.longyou.comm.conntroller.inner;

import static com.longyou.comm.CommonServiceConst.MESSAGE_LOG_COLLECTION;
import static com.unknow.first.geetest.GeetestErrorEnum.GEETEST_IS_NOT_OPEN;
import static org.cloud.constant.LoginTypeConstant._LOGIN_BY_THIRD_LOGIN;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cloud.parammanage.common.entity.ParamConfig;
import com.cloud.parammanage.common.service.ParamConfigService;
import com.longyou.comm.service.FrameUserRefService;
import com.longyou.comm.service.impl.UserInfoService;
import com.unknow.first.geetest.config.GeetestConfig;
import com.unknow.first.geetest.util.GeetestCheckUtil;
import com.unknow.first.geetest.vo.GeetestQueryParamVO;
import com.unknow.first.geetest.vo.GeetestValidateResultVO;
import com.unknow.first.mail.manager.domain.EmailSenderConfig;
import com.unknow.first.mail.manager.domain.EmailTemplate;
import com.unknow.first.mail.manager.service.EmailTemplateService;
import com.unknow.first.mail.manager.service.IEmailSenderConfigService;
import com.unkow.first.telegram.util.TelMsgSendUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.cloud.constant.CoreConstant;
import org.cloud.constant.CoreConstant.AuthMethod;
import org.cloud.context.RequestContextManager;
import org.cloud.dimension.annotation.SystemResource;
import org.cloud.entity.LoginUserDetails;
import org.cloud.exception.BusinessException;
import org.cloud.logs.annotation.AuthLog;
import org.cloud.vo.FrameUserRefVO;
import org.cloud.vo.MessageLogVO;
import org.cloud.vo.ParamConfigVO;
import org.cloud.vo.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 内部调用的controller
 */
@RestController
@RequestMapping("/inner")
@SystemResource(path = "/commonServiceInner")  //commonservice内部调用相关api
@Api(tags = "内部调用的controller")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class InnerCallController {

    private final FrameUserRefService frameUserRefService;
    private final EmailTemplateService emailTemplateService;
    private final IEmailSenderConfigService emailSenderConfigService;
    private final MongoTemplate mongoTemplate;
    private final ParamConfigService paramConfigService;
    private final UserInfoService userInfoService;
    private final GeetestConfig geetestConfig;

    /**
     * 内部调用的增加用户扩展信息的类，无权限控制，仅支持微服务间的调用
     *
     * @param vo
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "内部调用的增加用户扩展信息的类，无权限控制，仅支持微服务间的调用")
    @PostMapping("/userinfo/addUserRef")
    public Integer addUserRef(@RequestBody FrameUserRefVO vo) throws Exception {
        return frameUserRefService.create(vo);
    }

    /**
     * 内部调用的增加用户扩展信息的类，无权限控制，仅支持微服务间的调用
     *
     * @param vo
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "内部调用的增加用户扩展信息的类，无权限控制，仅支持微服务间的调用")
    @PutMapping("/userinfo/updateUserRef")
    public Integer updateUserRef(@RequestBody FrameUserRefVO vo) throws Exception {
        return frameUserRefService.update(vo);
    }

    /**
     * 内部调用的增加用户扩展信息的类，无权限控制，仅支持微服务间的调用
     *
     * @param attributeName 属性名称
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "内部调用的获取当前用户扩展属性")
    @GetMapping("/userinfo/getCurrentUserRefByAttributeName")
    @SystemResource("内部使用的获取当前用户扩展属性")
    public FrameUserRefVO getCurrentUserRefByAttributeName(@RequestParam("name") String attributeName) throws Exception {
        LoginUserDetails loginUserDetails = RequestContextManager.single().getRequestContext().getUser();
        return frameUserRefService.getUserRefByAttributeName(loginUserDetails.getId(), attributeName);
    }

    /**
     * 内部调用的增加用户扩展信息的类，无权限控制，仅支持微服务间的调用
     *
     * @param attributeName 属性名称
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "内部调用的获取用户扩展属性")
    @GetMapping("/userinfo/getUserRefByAttributeName/{userId}")
    public FrameUserRefVO getUserRefByAttributeName(@PathVariable("userId") Long userId, @RequestParam("name") String attributeName)
        throws Exception {
        return frameUserRefService.getUserRefByAttributeName(userId, attributeName);
    }

    /**
     * 内部调用的增加用户扩展信息的类，无权限控制，仅支持微服务间的调用
     *
     * @param userName 用户名称
     * @return
     * @throws Exception
     */
    @ApiOperation(value = "根据用户名查询(APP)用户信息")
    @GetMapping("/userinfo/getUserByUserName")
    public LoginUserDetails getUserByUserName(@RequestParam("userName") String userName) throws Exception {
        return userInfoService.selectUserInfoByUsername(userName, _LOGIN_BY_THIRD_LOGIN);
    }

    @ApiOperation(value = "内部调用的获取邮件模板")
    @GetMapping("/email/getEmailTemplateByCode")
    public EmailTemplate getEmailTemplateByCode(@RequestParam("templateCode") String templateCode,
        @RequestParam(value = "language", defaultValue = "zh_CN") String language) {
        QueryWrapper<EmailTemplate> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("template_code", templateCode);
        queryWrapper.eq("language", language);
        return emailTemplateService.getOne(queryWrapper);
    }

    @ApiOperation(value = "内部调用的获取邮件发送配置")
    @GetMapping("/email/getAllSenderConfig")
    public List<EmailSenderConfig> getAllSenderConfig() {
        LambdaQueryWrapper<EmailSenderConfig> query = Wrappers.lambdaQuery();
        query.select(EmailSenderConfig::getUserName);
        return emailSenderConfigService.list(query);
    }

    @ApiOperation(value = "内部调用的获取邮件发送配置")
    @GetMapping("/email/getSenderConfigByUserName")
    public EmailSenderConfig getSenderConfigByUserName(@RequestParam("userName") String userName) {
        LambdaQueryWrapper<EmailSenderConfig> query = Wrappers.<EmailSenderConfig>lambdaQuery()
            .eq(EmailSenderConfig::getUserName, userName);
        return emailSenderConfigService.getBaseMapper().selectOne(query);
    }

    @ApiOperation(value = "内部调用的保存消息日志")
    @PostMapping("/message/log/save")
    public Boolean saveMessageLogs(@RequestBody MessageLogVO messageLogVO) {
        if ("success".equals(messageLogVO.getResult())) {
            messageLogVO.setContent("-");
        }
        mongoTemplate.save(messageLogVO, MESSAGE_LOG_COLLECTION);
        return true;
    }

    @ApiOperation(value = "内部调用的获取参数配置")
    @GetMapping("/param/config/get/{code}")
    public ParamConfigVO get(@PathVariable("code") String code) {
        return BeanUtil.toBean(paramConfigService.get(code), ParamConfigVO.class);
    }

    @ApiOperation(value = "内部调用的更新参数配置")
    @PostMapping("/param/config/update")
    public Boolean update(@RequestBody ParamConfigVO paramConfigVO) {
        ParamConfig paramConfig = paramConfigService.lambdaQuery().eq(ParamConfig::getConfigCode, paramConfigVO.getConfigCode()).one();
        if (paramConfig == null) {
            paramConfig = BeanUtil.toBean(paramConfigVO, ParamConfig.class);
            return paramConfigService.save(paramConfig);
        }
        return paramConfigService.updateByPrimaryKeySelective(BeanUtil.toBean(paramConfigVO, ParamConfig.class)) > 0;
    }

    @ApiOperation(value = "发送Telegram消息", notes = "发送Telegram消息,成功返回200")
    @PostMapping("/tel/send/msg")
    public int sendTelMsg(@ApiParam("Tel群聊ID") final String chatId, @ApiParam("消息列表") final String message,
        @ApiParam("消息格式，Markdown、MarkdownV2、html") String parseMode) {
        return TelMsgSendUtil.single().sendMessage(chatId, message, parseMode);
    }

    /**
     * 禁用用户
     *
     * @param username
     * @param userType
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/user/disabledUser/{username}/{userType}")
    @AuthLog(bizType = "framework", desc = "admin-禁用用户(Feign)", operateLogType = CoreConstant.OperateLogType.LOG_TYPE_BACKEND)
    public String disabledUser(@PathVariable("username") String username, @PathVariable("userType") String userType)
        throws Exception {
        return userInfoService.disabledUser(username, userType);
    }

    @AuthLog(bizType = "framework", desc = "admin-禁用用户(Feign)", operateLogType = CoreConstant.OperateLogType.LOG_TYPE_BACKEND)
    @ApiOperation(value = "admin-禁用用户", notes = "admin-禁用用户")
    @GetMapping(value = "/disabledUser/{userId}")
    public String disabledUser(@PathVariable("userId") Long userId) throws Exception {
        return userInfoService.disabledUser(userId);
    }

    /**
     * 启用用户
     *
     * @param username
     * @param userType
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/user/enabledUser/{username}/{userType}")
    public String enabledUser(@PathVariable("username") String username, @PathVariable("userType") String userType)
        throws Exception {
        return userInfoService.enabledUser(username, userType);
    }

    @ApiOperation(value = "admin-启用用户", notes = "admin-启用用户")
    @GetMapping(value = "/enabledUser/{userId}")
    public String enabledUser(@PathVariable("userId") Long userId) throws Exception {
        return userInfoService.enabledUser(userId);
    }


    /**
     * @param
     * @return
     */

    @PostMapping("/geetest/verify")
    @ApiOperation("geetest验证")
    @AuthLog(bizType = "geetest", desc = "geetest验证(inner)")
    public GeetestValidateResultVO geetestVerify(@RequestBody GeetestQueryParamVO requestParams) throws BusinessException {

        if (!geetestConfig.getEnabled()) { // 如果未开放，那么默认放过
            return GeetestValidateResultVO.builder().pass(true).msg(GEETEST_IS_NOT_OPEN.i18n).build();
        }
        return GeetestCheckUtil.handler.check(geetestConfig, requestParams);
    }
}
